<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8">
		<meta name="viewport"
			  content="width=device-width, user-scalable=no, initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0">
		<meta http-equiv="X-UA-Compatible" content="ie=edge">
		<title>铜锁SM2、SM3、SM4在线加密解密</title>
		<link rel="stylesheet" href="//unpkg.com/layui@2.6.8/dist/css/layui.css" />
		<script src="//unpkg.com/layui@2.6.8/dist/layui.js"></script>
	</head>
	<body>
		<div style="padding: 20px 20px">
			<div class="layui-tab">
				<ul class="layui-tab-title">
					<li class="layui-this">SM4加解密算法</li>
					<li>SM3杂凑算法</li>
					<li>SM2签名和验签</li>
				</ul>
				<div class="layui-tab-content">
					<div class="layui-tab-item layui-show">
						<div class="layui-row layui-anim-scale pt10" style="width: 100%;">
							<div class="layui-col-md5">
								<textarea style="resize: none;min-height: 280px;"
										  placeholder="在此输入明文，选择对应的加密⽅式，也可以加
入密钥，然后加密即可。" class="layui-textarea w99 fl m-h100"
										  id="msg_source"></textarea>
							</div>
							<div class="layui-col-md2">
								<form class="layui-form" action="" onsubmit="return !1;">
									<div class="layui-form-item layui-col-md-offset2">
										<div class="layui-input-inline fr w200 xpswd">
											<input type="text" name="text" id="pwd"
												   placeholder="在此输入密钥"
												   autocomplete="off"
												   class="layui-input">
										</div>
									</div>
									<div class="layui-form-item layui-col-md-offset2">
										<div class="layui-input-inline fr w200 mbt">
											<button class="layui-btn"
													onclick="decrypt();">
												<i class="layui-icon m-hide"></i>＜解密
											</button>
											<button class="layui-btn"
													onclick="encrypt();">加密＞<i
												   class="layui-icon m-hide"></i>
											</button>
										</div>
									</div>
								</form>
							</div>
							<div class="layui-col-md5">
								<textarea name="cipherr"
										  class="layui-textarea w99 fr "
										  placeholder="加密后的密文会显⽰在这⾥。也可以是待解密的密文。"
										  style="resize: none;min-height: 280px;" id="encrypt_result"
										  ondblclick="this.focus();this.select();"></textarea>
							</div>
						</div>
					</div>
					<div class="layui-tab-item">
						<div>
							<textarea style="resize: none;height: 200px;" placeholder="原文放到这⾥即可。"
									  class="layui-textarea w99 fl " id="source"
									  maxlength="1000"></textarea>
						</div>
						<div style="display: inline-block;margin-top: 10px;margin-bottom:20px;">
							<button class="layui-btn" id="ensm3" onclick="ensm3()">SM3加密＞
								<i class="layui-icon"></i></button>
						</div>
					</div>
					<div class="layui-tab-item">
						<div>
								<button type="button" class="layui-btn" id="sign_file">
											<i class="layui-icon">&#xe67c;</i>上传需要签名的文件
										</button>
										<div style="display: inline-block;margin-top: 10px;margin-bottom:20px;">
											<button class="layui-btn" id="sign" onclick="download()">
												下载签名文件＞<i class="layui-icon"></i>
											</button>
										</div>
									</div>
									<div>
										<button type="button" class="layui-btn" id="upload_origin_file">
											<i class="layui-icon">&#xe67c;</i>上传源文件
										</button>
										<button type="button" class="layui-btn" id="upload_sign_file">
											<i class="layui-icon">&#xe67c;</i>上传签名文件
										</button>
										<div style="display: inline-block;margin-top: 10px;margin-bottom:20px;">
											<button class="layui-btn" onclick="verify()">验证签名＞<i
												   class="layui-icon"></i>
											</button>
										</div>
									</div>
						</div>
					</div>
				</div>
			</div>
	</body>
	<script>
		function ajaxRequest(url, data, onSuccess, onError) {
		 var xhr = new XMLHttpRequest();
		 xhr.open('POST', url, true);
		 xhr.onreadystatechange = function () {
		 if (xhr.readyState === XMLHttpRequest.DONE) {
		 if (xhr.status === 200) {
		 onSuccess(JSON.parse(xhr.responseText));
		 } else {
		 onError(JSON.parse(xhr.statusText));
		 }
		 }
		 };
		 var formData = new FormData();
		 for (var key in data) {
		 formData.append(key, data[key]);
		 }
		 xhr.send(formData);
		 }
		 // 获取 id 为 msg_source 的元素
		 var source = document.getElementById('msg_source');
		 var source_text = document.getElementById('source');
		 var pwd = document.getElementById('pwd');
		 // 获取 id 为 encrypt_result 的元素
		 var result = document.getElementById('encrypt_result');
		 function encrypt() {
		 console.log('加密')
		 const v = source.value
		 const pass = pwd.value
		 if (!v || v === '') {
		 return alert('加密数据为空')
		 }
		 if (!pass || pass === '') {
		 return alert('密钥为空')
		 }
		 ajaxRequest('/sm4_cbc_encrypt', {'msg': v.trim(),
		'key': pass.trim()}, function (res) {
		 console.log(res);
		 result.value = res.output;
		 }, function (err) {
		 console.log(err);
		 })
		 }
		 function decrypt() {
		 console.log('解密')
		 const v = result.value.trim()
		 if (!v || v === '') {
		 return alert('解密数据为空')
		 }
		 const pass = pwd.value.trim()
		 if (!pass || pass === '') {
		 return alert('密钥为空')
		 }
		 ajaxRequest('/sm4_cbc_decrypt', {'msg': v, 'key':
		pass}, function (res) {
		 console.log(res);
		 if (res.error !== '') {
		 return layer.alert('解密失败:' + res.error, {'icon': 2});
		 }
		 source.value = res.output;
		 }, function (err) {
		console.log(err);
		 })
		 }
		 function ensm3() {
		 console.log('sm3加密')
		 const v = source_text.value
		 if (!v || v === '') {
		 return alert('加密数据为空')
		 }
		 ajaxRequest('/sm3_dgst', {'msg': v.trim()}, function
		(res) {
		 console.log(res);
		 source_text.value = res.output;
		 }, function (err) {
		 console.log(err);
		 })
		 }
		 var file_path = ''
		 var origin_file_path = ''
		 var sign_file_path = ''
		 function download() {
		 console.log('file_path')
		 if (!file_path || file_path === '') {
		 return alert('签名文件未上传')
		 }
		 var xhr = new XMLHttpRequest();
		 xhr.open('POST', '/download', true);
		 xhr.responseType = 'blob';
		 xhr.onload = function () {
		 if (xhr.status === 200) {
		 var blob = new Blob([xhr.response], {type: 'application/octetstream'});
		 var a = document.createElement('a');
		 a.href = window.URL.createObjectURL(blob);
		 a.download = Math.floor(Math.random() * 10000) + '_sign_file';
		 document.body.appendChild(a);
		 a.click();
		 document.body.removeChild(a);
		 layer.alert('下载签名文件成功', {'icon': 1});
		 } else {
		 console.log(xhr.statusText);
		 }
		 };
		 var fData = new FormData();
		 fData.append('file_path', file_path);
		 console.log(file_path);
		 console.log(fData)
		 xhr.send(fData);
		}
		 function verify() {
		 console.log('verify')
		 const v = source.value
		 if (!origin_file_path || origin_file_path === '') {
		 return alert('原始文件未上传！')
		 }
		 if (!sign_file_path || sign_file_path === '') {
		 return alert('签名文件未上传！')
		 }
		 ajaxRequest('/sm2_verify', {
		 'file_path': origin_file_path,
		 'sign_file_path': sign_file_path
		 }, function (res) {
		 console.log(res);
		 layer.alert(res.output);
		 }, function (err) {
		 console.log(err);
		 })
		 }
		 uploadFile('#sign_file', function (res) {
		 ajaxRequest('/sm2_sign', {'path': res.path}, function
		(sign_res) {
		 file_path = sign_res.path
		 }, function (sign_err) {
		 console.log(sign_err);
		 })
		 })
		 uploadFile('#upload_origin_file', function (res) {
		 origin_file_path = res.path
		 })
		 uploadFile('#upload_sign_file', function (res) {
		 sign_file_path = res.path
		 })
		 function uploadFile(elem, doneCallback, errorCallback) {
		 layui.use('upload', function () {
		 var upload = layui.upload;
		 //执⾏实例
		 var uploadInst = upload.render({
		 elem: elem,
		 accept: 'file',
		 url: '/upload',
		 done: function (res) {
		 doneCallback(res);
		 },
		 error: function () {
		 errorCallback();
		 }
		});
		 });
		 }
	</script>
</html>